﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TemplateTools {
    public class TemplateHelper {
        public static TemplateFieldDefinition[] GetFieldDefinitions(string template) {
            Dictionary<string, TemplateFieldDefinition> fieldDefinitions = new Dictionary<string, TemplateFieldDefinition>();
            TemplateField[] fields = GetFields(template);
            foreach (TemplateField field in fields) {
                if (!fieldDefinitions.ContainsKey(field.FieldDefinition.Name)) {
                    fieldDefinitions.Add(field.FieldDefinition.Name, field.FieldDefinition);
                }
            }
            return fieldDefinitions.Values.ToArray();
        }

        public static TemplateField[] GetFields(string template) {
            List<TemplateField> fields = new List<TemplateField>();
            for (int i = 0; i < template.Length; i++) {
                char ch = template[i];
                if (i < template.Length - 1 && (ch == '$' && template[i + 1] == '{')) {
                    int startLocation = i;
                    i += 2;
                    StringBuilder fieldDef = new StringBuilder();
                    for (; i < template.Length; i++) {
                        ch = template[i];
                        if (ch == '}') {
                            string fieldDefStr = fieldDef.ToString();
                            if (string.IsNullOrEmpty(fieldDefStr)) {
                                throw new Exception("Invalid field name '" + fieldDefStr + "'");
                            }
                            TemplateField field = TemplateField.Parse(startLocation, i - startLocation, fieldDefStr);
                            fields.Add(field);
                            break;
                        } else {
                            fieldDef.Append(ch);
                        }
                    }
                } else {
                    // skip
                }
            }
            return fields.ToArray();
        }

        public static string Render(string template, Dictionary<string, string> fieldValues) {
            TemplateField[] fields = GetFields(template);
            for (int i = fields.Length - 1; i >= 0; i--) {
                TemplateField field = fields[i];
                string value;
                if (!fieldValues.TryGetValue(field.FieldDefinition.Name, out value)) {
                    value = "";
                }
                template = field.Render(template, value);
            }
            template = template.Replace("{{", "{");
            return template;
        }
    }
}
